﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Data;
using GSSoftSL.Utility;
using GSSoftSL.Web;
using GSSoftSL.Web.Models;
using GSSoftSL.Web.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

namespace GSSoftSL.ViewModel
{
    public class KhoaHocViewModel : ViewModelBase
    {
        private bool _isBusy = false;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                _isBusy = value;
                RaisePropertyChanged("IsBusy");
            }
        }
        private GSSoftContext _dc;

        
        private Phong[] _phongs = null;
        public Phong[] Phongs
        {
            get
            {
                return _phongs;
            }
            set
            {
                if (_phongs == value)
                {
                    return;
                }
                _phongs = value;
                RaisePropertyChanged("Phongs");
            }
        }
        
        private CaHoc[] _caHocs = null;
        public CaHoc[] CaHocs
        {
            get
            {
                return _caHocs;
            }
            set
            {
                if (_caHocs == value)
                {
                    return;
                }
                _caHocs = value;
                RaisePropertyChanged("CaHocs");
            }
        }

        /// <summary>
        /// Initializes a new instance of the KhoaHocVewModel class.
        /// </summary>
        public KhoaHocViewModel()
        {
            Init();
        }

        private void Init()
        {
            _dc = new GSSoftContext();
            IsBusy = true;
            _dc.Load<Mon>(_dc.GetMonsQuery().OrderBy(n => n.ThuTu), LoadBehavior.RefreshCurrent, LoadMon_Completed, null);
            _dc.Load<GiaoVien>(_dc.GetGiaoViensWithDetailsQuery(), LoadBehavior.RefreshCurrent, LoadGiaoVien_Completed, null);
            _dc.Load<Phong>(_dc.GetPhongsQuery().OrderBy(n => n.Tang).ThenBy(n => n.MaPhong), LoadBehavior.RefreshCurrent, LoadPhong_Completed, null);
            _dc.Load<CaHoc>(_dc.GetCaHocsQuery().OrderBy(n => n.MaCaHoc), LoadBehavior.RefreshCurrent, LoadCaHoc_Completed, null);

        }

        private void LoadCaHoc_Completed(LoadOperation<CaHoc> load)
        {
            CaHocs = load.Entities.ToArray();
        }

        private void LoadPhong_Completed(LoadOperation<Phong> load)
        {
            Phongs = load.Entities.ToArray();
        }

        private void LoadGiaoVien_Completed(LoadOperation<GiaoVien> load)
        {
            _giaoViensFull = load.Entities.ToArray();
        }

        private void LoadMon_Completed(LoadOperation<Mon> load)
        {
            var res = load.Entities.ToList();
            res.Insert(0, new Mon()
                              {
                                  MaMon = "-1", 
                                  TenMon = "Chọn môn ..."
                              });
            Mons = res;
            Mon = Mons[0];
            IsBusy = false;
        }

        private GiaoVien[] _giaoViensFull = null;
        private GiaoVien[] _giaoViens = null;
        public GiaoVien[] GiaoViens
        {
            get
            {
                return _giaoViens;
            }
            set
            {
                if (_giaoViens == value)
                {
                    return;
                }
                _giaoViens = value;
                RaisePropertyChanged("GiaoViens");
            }
        }

        private List<Mon> _mons = null;
        public List<Mon> Mons
        {
            get
            {
                return _mons;
            }
            set
            {
                if (_mons == value)
                {
                    return;
                }
                _mons = value;
                RaisePropertyChanged("Mons");
            }
        }
        
        
        private Mon _mon = null;
        public Mon Mon
        {
            get
            {
                return _mon;
            }
            set
            {
                if (_mon == value)
                {
                    return;
                }
                _mon = value;
                RaisePropertyChanged("Mon");
                if (_mon == null || _mon.MaMon == "-1")
                {
                    CanAddNew = false;
                    KhoaHoc = null;
                    KhoaHocs = null;
                    Lops = null;
                    Lop = null;
                }
                else
                {
                    IsBusy = true;
                    _dc.Load(_dc.GetLopsQuery().Where(n => n.MaMon == _mon.MaMon).OrderBy(n => n.TrangThai).ThenBy(n => n.MaLop), LoadBehavior.RefreshCurrent,
                             LoadLop_Completed, null);
                    if (_showAllGiaoVien)
                    {
                        GiaoViens = _giaoViensFull;
                    }
                    else
                    {
                        GiaoViens = _giaoViensFull.Where(n => n.GiaoVienMons.Any(m => m.MaMon == _mon.MaMon)).ToArray();
                    }
                }
            }
        }

        private void LoadLop_Completed(LoadOperation<Lop> load)
        {
            var res = load.Entities.ToList();
            res.Insert(0, new Lop()
                              {
                                  LopId = new Guid(),
                                  MaLop = "-1",
                                  TenLop = "Chọn lớp ..."
                              });
            Lops = res;
            Lop = res[0];
            IsBusy = false;
        }

        private List<Lop> _lops = null;
        public List<Lop> Lops
        {
            get
            {
                return _lops;
            }
            set
            {
                if (_lops == value)
                {
                    return;
                }
                _lops = value;
                RaisePropertyChanged("Lops");
            }
        }
        
        
        private Lop _lop = null;
        public Lop Lop
        {
            get
            {
                return _lop;
            }
            set
            {
                if (_lop == value)
                {
                    return;
                }
                _lop = value;
                RaisePropertyChanged("Lop");
                if (_lop == null || _lop.MaLop == "-1")
                {
                    CanAddNew = false;
                    KhoaHoc = null;
                    KhoaHocs = null;
                }
                else
                {
                    IsBusy = true;
                    _dc.Load(_dc.GetKhoaHocsWithChiTietQuery().Where(n => n.LopId == _lop.LopId).OrderByDescending(n => n.STT), LoadBehavior.RefreshCurrent, LoadKhoaHoc_Completed, null);
                }
            }
        }

        private void LoadKhoaHoc_Completed(LoadOperation<KhoaHoc> load)
        {
            KhoaHocs = new PagedCollectionView(load.Entities.ToList());
            IsBusy = false;
            CanAddNew = true;
        }

        private PagedCollectionView _khoaHocs = null;
        public PagedCollectionView KhoaHocs
        {
            get
            {
                return _khoaHocs;
            }
            set
            {
                if (_khoaHocs == value)
                {
                    return;
                }
                _khoaHocs = value;
                RaisePropertyChanged("KhoaHocs");
            }
        }

        private KhoaHoc _khoaHoc = null;
        public KhoaHoc KhoaHoc
        {
            get
            {
                return _khoaHoc;
            }
            set
            {
                if (_khoaHoc == value)
                {
                    return;
                }
                _khoaHoc = value;
                RaisePropertyChanged("KhoaHoc");
                if (_isEditable)
                {
                    _cancelCommand.Execute(null);
                    IsEditable = false;
                }
                else
                {
                    
                }
                CanEdit = _khoaHoc != null;
            }
        }
        
        private KhoaHocChiTiet _khoaHocChiTiet = null;
        public KhoaHocChiTiet KhoaHocChiTiet
        {
            get
            {
                return _khoaHocChiTiet;
            }
            set
            {
                if (_khoaHocChiTiet == value)
                {
                    return;
                }
                _khoaHocChiTiet = value;
                RaisePropertyChanged("KhoaHocChiTiet");
            }
        }

        private RelayCommand _newCommand;
        public RelayCommand NewCommand
        {
            get
            {
                return _newCommand
                    ?? (_newCommand = new RelayCommand(
                                          () =>
                                          {
                                              _cancelCommand.Execute(null);
                                              /*if (_dc.HasChanges)
                                              {
                                                  _dc.RejectChanges();
                                              }
                                              KhoaHocs.CancelNew();
                                              if (KhoaHocs.CanCancelEdit)
                                                  KhoaHocs.CancelEdit();*/
                                              KhoaHoc = (KhoaHoc)KhoaHocs.AddNew();
                                              KhoaHoc.MaKhoaHoc = "";
                                              KhoaHoc.NgayKhaiGiang = KhoaHoc.BatDau = DateTime.Now.Date;
                                              KhoaHoc.KetThuc = KhoaHoc.BatDau.AddDays(1);
                                              KhoaHocs.MoveCurrentTo(KhoaHoc);
                                              //KhoaHoc = new KhoaHoc() { MaKhoaHoc = "" };
                                              SetStatus(EnumAction.New);
                                          }));
            }
        }

        private RelayCommand _editCommand;
        public RelayCommand EditCommand
        {
            get
            {
                return _editCommand
                    ?? (_editCommand = new RelayCommand(
                                          () =>
                                          {
                                              if (_khoaHoc == null || _khoaHoc.EntityState == EntityState.New || _khoaHoc.EntityState == EntityState.Detached)
                                                  return;
                                              SetStatus(EnumAction.Edit);
                                          }));
            }
        }

        private RelayCommand _saveCommand;
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand
                    ?? (_saveCommand = new RelayCommand(
                                          () =>
                                          {
                                              if (KhoaHoc == null || _dc.IsSubmitting)
                                                  return;
                                              string message = null;
                                              if (!Validate(ref message))
                                              {
                                                  MessageWindow.CreateNew("Thông tin không hợp lệ", message);
                                                  return;
                                              }
                                              ConfirmWindow.CreateNew("Bạn có muốn lưu?", Save);
                                              SetStatus(EnumAction.Save);
                                          }));
            }
        }

        public bool Validate(ref string Message)
        {
            if (string.IsNullOrWhiteSpace(_khoaHoc.TenKhoaHoc))
            {
                Message = "Vui lòng nhập thông tin tên khóa học.";
                return false;
            }
            if (_khoaHoc.BatDau > _khoaHoc.KetThuc)
            {
                Message = "Ngày bắt đầu khóa học phải trước ngày kết thúc.";
                return false;
            }
            return true;
        }

        public void Save()
        {
            if (KhoaHoc.EntityState == EntityState.New || KhoaHoc.EntityState == EntityState.Detached)
            {
                IsBusy = true;
                KhoaHoc.KhoaHocId = Guid.NewGuid();
                //KhoaHoc.MaKhoaHoc = "";
                //KhoaHoc.STT = 1;
                KhoaHoc.Lop = Lop;
                KhoaHoc.NgayTao = KhoaHoc.NgayCapNhat = DateTime.Now;
                KhoaHoc.NguoiTao = KhoaHoc.NguoiCapNhat = UtilityFunction.GetCurrentUserId();
                _dc.KhoaHocs.Add(KhoaHoc);
                KhoaHocs.CommitNew();
            }
            else if (KhoaHoc.EntityState == EntityState.Modified)
            {
                //CurrentLop.KhoaHocs.Add(CurrentKhoaHoc);
                GiaoVien gv = KhoaHoc.GiaoVien;
                KhoaHoc.Lop = Lop;
                //KhoaHoc.GiaoVien = null;
                KhoaHoc.GiaoVien = gv;
                KhoaHoc.NgayCapNhat = DateTime.Now;
                KhoaHoc.NguoiCapNhat = UtilityFunction.GetCurrentUserId();
                IsBusy = true;
                KhoaHocs.CommitEdit();
            }
            
            _dc.SubmitChanges(Save_Completed, KhoaHoc.EntityState);
        }

        private void Save_Completed(SubmitOperation obj)
        {
            //if ((EntityState)obj.UserState == EntityState.New)
                //KhoaHocs.
            IsBusy = false;
        }

        private RelayCommand _cancelCommand;
        public RelayCommand CancelCommand
        {
            get
            {
                return _cancelCommand
                    ?? (_cancelCommand = new RelayCommand(
                                          () =>
                                          {
                                              SetStatus(EnumAction.Cancel);
                                              //KhoaHocs.CancelNew();
                                              if (KhoaHocs.CanCancelEdit)
                                                  KhoaHocs.CancelEdit();
                                              KhoaHocs.CancelNew();
                                              if (_khoaHoc != null && (_khoaHoc.EntityState == EntityState.New || _khoaHoc.EntityState == EntityState.Detached))
                                              {
                                                  KhoaHoc = null;
                                                  //KhoaHocs.CancelNew();
                                              }
                                              if (_dc.HasChanges)
                                                  _dc.RejectChanges();
                                          }));
            }
        }

        private RelayCommand _refreshCommand;
        public RelayCommand RefreshCommand
        {
            get
            {
                return _refreshCommand
                    ?? (_refreshCommand = new RelayCommand(Init));
            }
        }

        private RelayCommand<KhoaHocChiTiet> _addBuoiHocCommand;
        public RelayCommand<KhoaHocChiTiet> AddBuoiHocCommand
        {
            get
            {
                return _addBuoiHocCommand
                    ?? (_addBuoiHocCommand = new RelayCommand<KhoaHocChiTiet>(
                                          o =>
                                          {
                                              KhoaHoc.KhoaHocChiTiets.Add(o);
                                          }));
            }
        }

        private RelayCommand _editBuoiHocCommand;
        public RelayCommand EditBuoiHocCommand
        {
            get
            {
                return _editBuoiHocCommand
                    ?? (_editBuoiHocCommand = new RelayCommand(
                                          () =>
                                          {
                                              
                                          }));
            }
        }

        private RelayCommand _removeBuoiHocCommand;
        public RelayCommand RemoveBuoiHocCommand
        {
            get
            {
                return _removeBuoiHocCommand
                    ?? (_removeBuoiHocCommand = new RelayCommand(
                                          () =>
                                          {
                                              
                                          }));
            }
        }

        private bool _isEditable = false;
        public bool IsEditable
        {
            get
            {
                return _isEditable;
            }
            set
            {
                if (_isEditable == value)
                {
                    return;
                }
                _isEditable = value;
                RaisePropertyChanged("IsEditable");
            }
        }
        
        private bool _canAddNew = false;
        public bool CanAddNew
        {
            get
            {
                return _canAddNew;
            }
            set
            {
                if (_canAddNew == value)
                {
                    return;
                }
                _canAddNew = value;
                RaisePropertyChanged("CanAddNew");
            }
        }

        private bool _canEdit = false;
        public bool CanEdit
        {
            get
            {
                return _canEdit;
            }
            set
            {
                if (_canEdit == value)
                {
                    return;
                }
                _canEdit = value;
                RaisePropertyChanged("CanEdit");
            }
        }

        private bool _canSave = false;
        public bool CanSave
        {
            get
            {
                return _canSave;
            }
            set
            {
                if (_canSave == value)
                {
                    return;
                }
                _canSave = value;
                RaisePropertyChanged("CanSave");
            }
        }

        private bool _canCancel = false;
        public bool CanCancel
        {
            get
            {
                return _canCancel;
            }
            set
            {
                if (_canCancel == value)
                {
                    return;
                }
                _canCancel = value;
                RaisePropertyChanged("CanCancel");
            }
        }

        
        private bool _showAllGiaoVien = false;
        public bool ShowAllGiaoVien
        {
            get
            {
                return _showAllGiaoVien;
            }
            set
            {
                if (_showAllGiaoVien == value)
                {
                    return;
                }
                _showAllGiaoVien = value;
                RaisePropertyChanged("ShowAllGiaoVien");
                if (_giaoViensFull != null)
                {
                    GiaoVien temp = null;
                    if (_khoaHoc != null && _khoaHoc.GiaoVien != null)
                        temp = _khoaHoc.GiaoVien;
                    if (_showAllGiaoVien)
                        GiaoViens = _giaoViensFull;
                    else if (_mon != null && _mon.MaMon != "-1")
                        GiaoViens = _giaoViensFull.Where(n => n.GiaoVienMons.Any(m => m.MaMon == _mon.MaMon)).ToArray();
                    if (temp != null)
                        _khoaHoc.GiaoVien = temp;
                }
            }
        }

        public void SetStatus(EnumAction Action)
        {
            switch (Action)
            {
                case EnumAction.New:
                    IsEditable = true;
                    CanSave = true;
                    CanCancel = true;
                    CanEdit = false;
                    break;
                case EnumAction.Save:
                    IsEditable = false;
                    CanSave = false;
                    CanCancel = false;
                    CanEdit = true;
                    break;
                case EnumAction.Edit:
                    IsEditable = true;
                    CanSave = true;
                    CanCancel = true;
                    CanEdit = false;
                    break;
                case EnumAction.Cancel:
                    IsEditable = false;
                    CanSave = false;
                    CanCancel = false;
                    if (_khoaHoc != null && (_khoaHoc.EntityState == EntityState.Modified || _khoaHoc.EntityState == EntityState.Unmodified))
                    {
                        CanEdit = true;
                    }
                    break;
                case EnumAction.Detail:
                    IsEditable = false;
                    CanSave = false;
                    CanCancel = false;
                    CanEdit = true;
                    break;
            }
        }

    }
}